package com.jfinal.web;

import com.jfinal.kit.StrKit;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.Map;

/**
 * Created by CHEN on 15/7/10.
 */
public class WebKit {

    public static final String REQUEST_BODY = "__REQUEST_BODY__";


    public static String getUrlWithParams(HttpServletRequest req) {
        String uri = req.getRequestURI();
        String param = "";
        if (req.getQueryString() != null) {
            try {
                param = new String(req.getQueryString().getBytes("ISO8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        if (!param.equals("")) uri += "?" + param;
        return uri;
    }

    public static boolean isRequestMethod(HttpServletRequest req, String method) {
        return req.getMethod().equalsIgnoreCase(method);
    }

    public static boolean isPostMethod(HttpServletRequest req) {
        return isRequestMethod(req, "post");
    }

    public static boolean isGetMethod(HttpServletRequest req) {
        return isRequestMethod(req, "get");
    }


    /**
     * @param request
     * @return
     * @throws IOException
     */
    public static String getPayload(HttpServletRequest request) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;

        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        return stringBuilder.toString();
    }

    public static String getRequestBody(HttpServletRequest request) {
        //特殊处理，避免丢失请求参数
        Map<String, String[]> paramMap = request.getParameterMap();
        String requestBody = (String) request.getAttribute(REQUEST_BODY);
        if (requestBody == null) {
            try {
                requestBody = getPayload(request);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            if (requestBody != null) {
                request.setAttribute(REQUEST_BODY, requestBody);
            }
        }
        return requestBody;
    }


    public static boolean isAjax(HttpServletRequest req) {
        return req.getHeader("X-Requested-With") != null;
    }

    public static String getClientIP(HttpServletRequest req) {

        String ip = req.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = req.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = req.getRemoteAddr();
        }
        // 如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值
        // 取X-Forwarded-For中第一个非unknown的有效IP字符串
        // 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130,
        // 192.168.1.100
        // 用户真实IP为： 192.168.1.110
        if (ip != null && ip.indexOf(",") != -1) {
            for (String str : ip.split(",")) {
                if (!"unkown".equalsIgnoreCase(str)) {
                    ip = str;
                    break;
                }
            }
        }
        return ip;
    }

    /**
     * 获取serverName，适用于代理的情况，包含端口号
     */
    public static String getServerName(HttpServletRequest req) {
        String serverName = req.getHeader("X-FORWARDED-HOST");
        if (serverName == null || serverName.length() < 1) {
            serverName = req.getServerName() + (req.getServerPort() == 80 ? "" : (":" + req.getServerPort()));
        } else if (serverName.contains(",")) {
            serverName = serverName.substring(0, serverName.indexOf(",")).trim();
        }
        return serverName;
    }


    /**
     * 获取访问url的前缀，从http://一直包含到contextPath
     */
    public static String getUrlPrefix(HttpServletRequest req) {
        String url = req.getScheme() + "://";
        url += getServerName(req);
        url += req.getContextPath();
        return url;
    }

    static String[] mobileAgents = {"iphone", "android", "phone", "mobile", "wap", "netfront", "java", "opera mobi",
            "opera mini", "ucweb", "windows ce", "symbian", "series", "webos", "sony", "blackberry", "dopod", "nokia",
            "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma", "docomo",
            "up.browser", "up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos", "techfaith",
            "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson", "philips", "sagem", "wellcom", "bunjalloo",
            "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos", "pantech", "gionee", "portalmmm",
            "jig browser", "hiptop", "benq", "haier", "^lct", "320x320", "240x320", "176x220", "w3c ", "acs-", "alav",
            "alca", "amoi", "audi", "avan", "benq", "bird", "blac", "blaz", "brew", "cell", "cldc", "cmd-", "dang",
            "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs", "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g",
            "lge-", "maui", "maxo", "midp", "mits", "mmef", "mobi", "mot-", "moto", "mwbp", "nec-", "newt", "noki",
            "oper", "palm", "pana", "pant", "phil", "play", "port", "prox", "qwap", "sage", "sams", "sany", "sch-",
            "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem", "smal", "smar", "sony", "sph-", "symb", "t-mo",
            "teli", "tim-", "tsm-", "upg1", "upsi", "vk-v", "voda", "wap-", "wapa", "wapi", "wapp", "wapr", "webc",
            "winw", "winw", "xda", "xda-", "googlebot-mobile"};

    public static boolean isAjaxRequest(HttpServletRequest request) {
        String header = request.getHeader("X-Requested-With");
        return "XMLHttpRequest".equalsIgnoreCase(header);
    }

    public static boolean isMultipartRequest(HttpServletRequest request) {
        String contentType = request.getContentType();
        return contentType != null && contentType.toLowerCase().indexOf("multipart") != -1;
    }

    /**
     * 是否是手机浏览器
     */
    public static boolean isMoblieBrowser(HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        if (ua == null) {
            return false;
        }
        ua = ua.toLowerCase();
        for (String mobileAgent : mobileAgents) {
            if (ua.indexOf(mobileAgent) >= 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否是微信浏览器
     */
    public static boolean isWechatBrowser(HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        if (ua == null) {
            return false;
        }
        ua = ua.toLowerCase();
        if (ua.indexOf("micromessenger") > 0) {
            return true;
        }
        return false;
    }


    /**
     * 是否是PC版的微信浏览器
     */
    public static boolean isWechatPcBrowser(HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        if (ua == null) {
            return false;
        }
        ua = ua.toLowerCase();
        if (ua.indexOf("windowswechat") > 0) {
            return true;
        }
        return false;
    }

    /**
     * 是否是IE浏览器
     */
    public static boolean isIEBrowser(HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        if (ua == null) {
            return false;
        }

        ua = ua.toLowerCase();
        if (ua.indexOf("msie") > 0) {
            return true;
        }

        if (ua.indexOf("gecko") > 0 && ua.indexOf("rv:11") > 0) {
            return true;
        }
        return false;
    }

    public static String getIpAddress(HttpServletRequest request) {

        String ip = request.getHeader("X-requested-For");
        if (StrKit.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (StrKit.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StrKit.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StrKit.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StrKit.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StrKit.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        if (ip != null && ip.contains(",")) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }

        return ip;
    }

    public static String getUserAgent(HttpServletRequest request) {
        return request.getHeader("User-Agent");
    }


    public static String getReferer(HttpServletRequest request) {
        return request.getHeader("Referer");
    }



}
